import CryptoJS from 'crypto-js';

class Encryption {
    /**
     * 不足32位用8补齐
     * @param {string} str
     * @return {string}
     */
    static padStringTo32(str) {
        // 将字符串填充到32位，不足的部分用8补齐
        const paddedString = str.padEnd(32, '8');
        return paddedString;
    }

    static generateRandom16DigitNumber() {
        // 生成一个随机的16位数字字符串
        let randomNumber = '';
        for (let i = 0; i < 16; i++) {
            randomNumber += Math.floor(Math.random() * 10); // 生成0-9之间的随机数字
        }
        return randomNumber;
    }

    static stringToBase64(str) {
        // 将字符串转换为Base64编码
        const base64Str = CryptoJS.enc.Utf8.parse(str).toString(CryptoJS.enc.Base64);
        return base64Str;
    }

    static base64ToString(base64Str) {
        // 将Base64编码的字符串解码为原始字符串
        const originalStr = CryptoJS.enc.Base64.parse(base64Str).toString(CryptoJS.enc.Utf8);
        return originalStr;
    }

    static splitStringByDelimiter(str, delimiter) {
        // 使用指定的分隔符拆分字符串
        const parts = str.split(delimiter);
        return parts;
    }

    /**
     *  加密函数
     * @param plaintext
     * @param key
     * @returns {*}
     */
    static encrypt(plaintext, key) {
        try {
            const fullKey = this.padStringTo32(key)
            const stdKey =  fullKey.slice(0,32)
            // 将密钥和IV转换为WordArray
            const keyWordArray = CryptoJS.enc.Utf8.parse(stdKey);

            const iv = this.generateRandom16DigitNumber()
            const ivWordArray = CryptoJS.enc.Utf8.parse(iv);

            // 使用AES-256-CBC加密
            const encrypted = CryptoJS.AES.encrypt(plaintext, keyWordArray, {
                iv: ivWordArray,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });

            // 返回 base64 编码的结果
            return this.stringToBase64(iv + "::" + encrypted.ciphertext.toString(CryptoJS.enc.Base64));
        } catch (error) {
            console.error('Encryption failed:', error);
            throw error;
        }
    }

    /**
     *  解密函数
     * @param ciphertext
     * @param key
     * @returns {string}
     */
    static decrypt(ciphertext, key) {
        try {
            const fullKey = this.padStringTo32(key)
            const stdKey =  fullKey.slice(0,32)
            // 先解码字符串
            const mixString =  this.base64ToString(ciphertext);
            const splitParts = this.splitStringByDelimiter(mixString,"::")
            // 将密钥和IV转换为WordArray
            const keyWordArray = CryptoJS.enc.Utf8.parse(stdKey);
            const ivWordArray = CryptoJS.enc.Utf8.parse(splitParts[0]);

            // 将Base64编码的密文转换为WordArray
            const encryptedHex = CryptoJS.enc.Base64.parse(splitParts[1]);
            const encryptedWordArray = CryptoJS.lib.CipherParams.create({
                ciphertext: encryptedHex
            });

            // 使用AES-256-CBC解密
            const decrypted = CryptoJS.AES.decrypt(encryptedWordArray, keyWordArray, {
                iv: ivWordArray,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });
            return decrypted.toString(CryptoJS.enc.Utf8);
        } catch (error) {
            console.error('Decryption failed:', error);
            throw error;
        }
    }
}

export default Encryption;